package com.feituan.wx.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.feituan.core.exception.BusinessException;
import com.feituan.core.exception.RequestInvalidException;
import com.feituan.core.persistence.service.IMemberAmountService;
import com.feituan.core.persistence.service.IRechargeRecordService;
import com.feituan.core.pojo.entity.IntegrationRecord;
import com.feituan.core.pojo.entity.MemberAmount;
import com.feituan.core.pojo.entity.RechargeRecord;
import com.feituan.core.pojo.request.RechargeRecordReq;
import com.feituan.core.pojo.response.Response;
import com.feituan.core.pojo.response.page.PageData;
import com.feituan.wx.service.NewRechargeRecordService;
import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Response;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyV3Result;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 充值记录
 */
@RestController
@RequestMapping("/rechargeRecord")
public class RechargeRecordController {

    private final static Logger logger = LoggerFactory.getLogger(RechargeRecordController.class);

    @Resource
    private IRechargeRecordService rechargeRecordService;

    @Resource
    private NewRechargeRecordService recordService;

    @Resource
    private WxPayService wxPayService;

    @Resource
    private IMemberAmountService memberAmountService;


    /**
     * 新增余额充值记录
     * @param rechargeRecord rechargeRecord
     * @return
     */
    @PostMapping("/submit")
    public Response<Long> save(RechargeRecord rechargeRecord, Long memberAmountId) {
        MemberAmount memberAmount = memberAmountService.getBaseMapper().selectById(memberAmountId);
        rechargeRecord.setPrice(memberAmount.getPrice());
        rechargeRecord.setMemberAmountId(memberAmountId);
        return Response.success(rechargeRecordService.saveRecord(rechargeRecord));
    }

    /**
     * 预支付
     * @param request req
     * @param id 余额记录id
     * @return
     */
    @PostMapping("/prepay")
    public Response<WxPayUnifiedOrderV3Result.JsapiResult> prepay(HttpServletRequest request, Long id) {
        if (id == null) {
            throw new RequestInvalidException();
        }
        // 查询原记录
        RechargeRecord rechargeRecord = rechargeRecordService.selectById(id);
        if (rechargeRecord == null) {
            throw new RequestInvalidException();
        }
        WxPayUnifiedOrderV3Result.JsapiResult result = recordService.pay(rechargeRecord, request);
        return Response.success(result);
    }

   // @PostMapping("pay_notify")
    public String payNotify(@RequestBody String notifyData, HttpServletRequest request) {
        logger.info("pay notify start param :{}", notifyData);
        WxPayNotifyV3Result result = null;
        try {
            result = this.wxPayService.parseOrderNotifyV3Result(notifyData, this.getRequestHeader(request));
        } catch (WxPayException e) {
            return WxPayNotifyV3Response.fail("fail");
        }
        // 解密后的数据
        WxPayNotifyV3Result.DecryptNotifyResult notifyResult = result.getResult();
        logger.info("pay notify parsed param：{}", JSONObject.toJSONString(notifyResult));
        if (WxPayConstants.WxpayTradeStatus.PAY_ERROR.equals(notifyResult.getTradeState())) {
            logger.error("【pay notify error:{}", result);
            return WxPayNotifyV3Response.fail("fail");
        }
        if (WxPayConstants.WxpayTradeStatus.SUCCESS.equals(notifyResult.getTradeState())) {
            try {
                recordService.dtsPayNotify(notifyResult);
            } catch (BusinessException e) {
                return WxPayNotifyV3Response.fail("fail");
            } catch (Exception e) {
                logger.info("pay notify error :{}", e);
                return WxPayNotifyV3Response.fail("fail");
            }
        }

        logger.info("pay notify complete");
        return WxPayNotifyV3Response.success("ok");
    }


    /**
     * 获取回调请求头：签名相关
     *
     * @param request HttpServletRequest
     * @return SignatureHeader
     */
    public SignatureHeader getRequestHeader(HttpServletRequest request) {
        // 获取通知签名
        String signature = request.getHeader("Wechatpay-Signature");
        String nonce = request.getHeader("Wechatpay-Nonce");
        String serial = request.getHeader("Wechatpay-Serial");
        String timestamp = request.getHeader("Wechatpay-Timestamp");

        SignatureHeader signatureHeader = new SignatureHeader();
        signatureHeader.setSignature(signature);
        signatureHeader.setNonce(nonce);
        signatureHeader.setSerial(serial);
        signatureHeader.setTimeStamp(timestamp);
        return signatureHeader;
    }


    @PostMapping("/select_page")
    public PageData<RechargeRecord> selectList(RechargeRecordReq rechargeRecord) {
        Page<RechargeRecord> page = new Page<>();
        page.setCurrent(rechargeRecord.getPage());
        page.setSize(rechargeRecord.getLimit());
        LambdaQueryWrapper<RechargeRecord> qw = new LambdaQueryWrapper<>();
        qw.eq(rechargeRecord.getUserId() != null, RechargeRecord::getUserId, rechargeRecord.getUserId());
        qw.eq(rechargeRecord.getStatus() != null, RechargeRecord::getStatus, rechargeRecord.getStatus());
        Page<RechargeRecord> rechargeRecordPage = this.rechargeRecordService.getBaseMapper().selectPage(page, qw);
        return PageData.build(rechargeRecordPage.getCurrent(), rechargeRecordPage.getTotal(), rechargeRecordPage.getRecords());
    }


}
